<template>
  <div class="event-wrapper" ref="event">
      <div 
        :class="['event-cell', item.drop ? 'event-drop' : '', item.active ? 'active' : '', item.isEdit ? '' : 'event-cell-disabled']" 
        ref="slot" 
        v-for="(item, index) in weekEvent" 
        :key="item.id" 
        :style="getStyle(item)" 
        :data-id="item.id"
        :data-index="index"
        data-type="event"
        :data-disabled="true"
        @mousedown="getEvent($event, index)"
        @mouseup="itemUp($event,item)"
        @mouseover="itemOver($event)"
       >
       <el-popover
            :placement="placement"
            :width="270"
            trigger="hover"
            popper-class="event-detail-pop"
            :persistent="false"
        >
            <template #reference>
                <div :class="['event-content', item.complete ? 'event-complete' : '']" :data-id="item.id">
                    <el-tag size="small" style="margin-right:5px" @click.stop.prevent="jumpModel($event, index)" v-if="item.relateItems && item.relateItems.length > 0">
                        {{ (item.relateItems && item.relateItems.length > 0) ? item.relateItems[0].label : '' }}
                    </el-tag>
                    <slot name="week" :targetType="item.targetType" :codeName="item.codeName" :state="item.state" :title="item.title" :hours="item.hours"></slot>
                    <slot name="day" :targetType="item.targetType" :codeName="item.codeName" :state="item.state" :title="item.title" :hours="item.hours"></slot>
                    <!-- <el-checkbox size="small" @change="eventStatusChange($event, index)" style="margin-left:5px" /> -->
                </div>
            </template>
            <div class="event-detail">
                <el-row align="middle" justify="start" style="border-bottom: 1px solid #f0f0f0;padding-bottom: 5px;">
                    <el-button
                        size="small"
                        type="primary"
                        link
                        :icon="View"
                        @click="readInfo(item)"
                        >查看</el-button
                    >
                    <el-button 
                        v-if="item.state == 0 && item.sponsor.userId == userId"
                        size="small" 
                        type="primary" 
                        link 
                        @click="editInfo(item)"
                    >
                        <edit-two theme="outline" size="14" style="margin-right:5px;" />编辑
                    </el-button>
                    <el-button 
                        v-if="item.state == 0 || item.state == 1"
                        size="small" 
                        type="primary" 
                        link 
                        @click="completeEvent(item, index)" 
                        style="margin-left:0;"
                    >
                        <done-all theme="outline" size="16" style="margin-right:5px"/>
                        完成
                    </el-button>
                    <el-button 
                        v-if="
                            item.state == -2 || 
                            (item.state == 0 && item.sponsor.id == userId) || 
                            (item.state == 1 && item.sponsor.id == userId) ||
                            item.state == 2 || item.state == 3 || item.state == 4 || item.state == 5
                        "
                        size="small" 
                        type="danger" 
                        link 
                        style="margin-left:0" 
                        @click="delEvent(item)"
                    >
                        <delete theme="outline" size="14" style="margin-right:5px;" />
                        删除
                    </el-button>
                    <el-button 
                        v-if="item.state == -1 && item.approverIds.includes(userId)"
                        size="small"
                        type="primary"
                        link
                        style="margin-left: 0; margin-top: 2px"
                        @click="approverAccess(item)"
                    >
                        <el-icon><Check /></el-icon>
                        通过
                    </el-button>
                    <el-button 
                        v-if="item.state == -1 && item.approverIds.includes(userId)"
                        size="small"
                        type="danger"
                        link
                        style="margin-left: 0; margin-top: 2px"
                        @click="approverReject(item)"
                    >
                        <close theme="outline" size="14" style="margin-right: 5px; margin-top: 1px" />
                        拒绝
                    </el-button>
                </el-row>
                <el-row justify="start" style="margin: 10px 0;flex-wrap: nowrap;">
                    <round 
                    style="margin: 0 6px 0 2px"
                    theme="filled" 
                    size="8" 
                    fill="#18a058" 
                    />
                    <div class="event-detail-data">{{ item.title }}</div>
                </el-row>
                <el-row style="flex-wrap:nowrap;align-items: flex-start;">
                    <calendar-dot theme="outline" size="14" />
                    <div class="event-detail-data">{{ formatDurationTime(item) }}</div>
                </el-row>
                <el-row style="margin-top:5px;flex-wrap: nowrap;">
                    <user theme="outline" size="14" />
                    <div class="event-detail-data">{{ (item.relateItems && item.relateItems.length > 0) ? item.relateItems[0].label : '-' }}</div>
                </el-row>
                <el-row justify="start" style="margin-top: 5px;flex-wrap: nowrap;">
                    <el-icon style="margin-right: 8px;margin-top: 4px;" color="#18a058"><CollectionTag /></el-icon>
                    <el-tag size="small" class="showAllTag">{{ item.codeName }}</el-tag>
                </el-row>
            </div>
        </el-popover>
        <div class="event-arrow" @mousedown.prevent.stop="eventResize"></div>
      </div>
  </div>
</template>

<script>
import { computed, ref, toRefs, watch, onMounted, nextTick} from 'vue'
import { CalendarDot, User, EditTwo, DoneAll, Delete, Round, Close } from '@icon-park/vue-next';
import { checkCurrentWeekEvents, getAnyTimeEvent, formatTime } from '../lib/event'
import { format, formatShortTime } from '../lib/utils'
import { CollectionTag, Check, View } from '@element-plus/icons-vue'
import Cookies from 'js-cookie'
export default {
    name: 'EventItem',
    props: {
        events: {
            type: Array,
            default() {
                return []
            }
        },
        view: { // 视图
            type: String,
            default: null
        },
        hours: {
            type: Array,
            default() {
                return []
            }
        },
        week: {
            type: Array,
            default() {
                return []
            }
        },
        date: {
            type: String,
            default: null
        },
        dropData: {
            type: Object,
            default() {
                return {}
            }
        }
    },
    components: {
        CalendarDot,
        User,
        EditTwo,
        DoneAll, 
        Delete,
        Round,
        CollectionTag,
        Check,
        Close
    },
    setup(props, context) {
        const { view, hours, events, week, date, dropData } = toRefs(props)
        let weekEvent = ref([])
        let len = week.value.length
        const hourLen = hours.value.length
        const splitStart = hours.value[0].split(':') // 起始时间
        const splitEnd = hours.value[hourLen - 1].split(':') // 结束时间
        let dropMessage = ref(dropData.value)
        const startHour = splitStart[0] - 0 + splitStart[1] / 60 // 时间表开始的时间戳
        const endHour = splitEnd[0] - 0 + splitEnd[1] / 60 // 时间表结束的时间戳
        const placement = ref('left-start') // pop框的位置
        // eslint-disable-next-line no-unused-vars
        const dragStartPostion = {
            y: 0,
            x: 0
        }
        const selectedInfo = ref(null)
        const clickStart = ref(null)
        let dropIndex = -1
        let dropInfo = {}
        let canUp = true
        const userId = Cookies.get('userId')
        let eventModel = ref({
            top: `unset`,
            left: `unset`,
            right: `unset`,
            bottom: `unset`,
            background: ``,
            width: ``
        })

        // 获取事件
        const getCurrentWeek = () => {
            if(view.value == 'week') {
                weekEvent.value = checkCurrentWeekEvents(events.value, week.value) || []
            }else if(view.value == 'day') {
                weekEvent.value = getAnyTimeEvent(date.value, events.value) || []
            }
        }
        const getStyle = computed(() => {
            return (item) => {
                if(view.value == 'week') {
                    // 周
                    const position = getWeekPosition(item)
                    return {
                        ...position
                    }
                } else if(view.value == 'day') {
                    // 天
                    const position = getDayPosition(item)
                    return {
                        ...position
                    }
                }
            }
        })
        // 周事件定位
        const getWeekPosition = e => {
            let top = 0,left = 0,display = 'block', width = 100 / len, zIndex = 5;
            const currentTime = e.hours.split(' - ') // 当前的时间

            const TimeStart = currentTime[0].split(':') // 当前时间的切割
            const TimeEnd = currentTime[1].split(':') // 

            const startTemp = (TimeStart[0] - 0 + TimeStart[1] / 60) - startHour // 距开始时间
            const endTemp = endHour - (TimeStart[0] - 0 + TimeStart[1] / 60) + 1 // 距结束时间
            
            let height = ((TimeEnd[0] - 0 + TimeEnd[1] / 60) - (TimeStart[0] - 0 + TimeStart[1] / 60)) * 40
            const day = e.startDay == 0 ? 7 : e.startDay
            if(startTemp < 0 || endTemp < 0) {
                top = 0
                left = 0
                display = 'none'
            }else{
                top = (startTemp * 40) + 'px'
                // 获取当前时间段有多少事件
                const currentArr = getAnyTimeEvent(e.actionStartTime, weekEvent.value, 'time', (e.end - e.start))
                currentArr.sort((a, b) => {
                    if(a.release === b.release){
                        return a.id - b.id
                    }else{
                        return a.release - b.release
                    }
                })
                const currentArr_len = currentArr.length
                const findIndex = currentArr.findIndex(item => {
                    return item.id == e.id
                })
                left = `calc((100% / ${len} - 11.5px) * (${day-1}))`
                if(currentArr_len > 1) {
                    width = (width - 0.4) * ((currentArr_len - findIndex) / currentArr_len)
                    if(width < 5){
                        width = 5
                    }
                    zIndex += findIndex
                    if(findIndex > 0) {
                        left = `calc((100% / ${len} - 11.5px) * (${day-1}) + ${(100 / len - 0.4) - width}%)`
                    }
                }else{
                   width = width - 0.4
                }
                if(width < 5){
                    width = 5
                }
            }
            if(height <= 0) height = 26
            return {
                top,
                left,
                height: height + 'px',
                display,
                width: width < 0 ? 0 : `calc(${width}% - 12px)`,
                zIndex,
                background: e.background,
                color: e.color,
                resize: e.isEdit ? 'vertical' : 'none'
            }
        }
        // 天事件定位
        const getDayPosition = e => {
            let top = 0,left = 0,display = 'block', width = 100, zIndex = 499;
            const currentTime = e.hours.split(' - ') // 当前的时间
            const TimeStart = currentTime[0].split(':') // 当前时间的切割
            const TimeEnd = currentTime[1].split(':') // 

            const startTemp = (TimeStart[0] - 0 + TimeStart[1] / 60) - startHour // 距开始时间
            const endTemp = endHour - (TimeStart[0] - 0 + TimeStart[1] / 60) + 1  // 距结束时间
            
            const height = ((TimeEnd[0] - 0 + TimeEnd[1] / 60) - (TimeStart[0] - 0 + TimeStart[1] / 60)) * 40
            if(startTemp < 0 || endTemp < 0) {
                top = 0
                left = 0
                display = 'none'
            }else{ 
                top = (startTemp * 40) + 'px'
                // 获取当前时间段有多少事件
                const currentArr = getAnyTimeEvent(e.actionStartTime, weekEvent.value, 'time', (e.end - e.start))
                currentArr.sort((a, b) => {
                    if(a.release === b.release){
                        return a.id - b.id
                    }else{
                        return a.release - b.release
                    }
                })
                const currentArr_len = currentArr.length
                const findIndex = currentArr.findIndex(item => {
                    return item.id == e.id
                })
                left = 0
                if(currentArr_len > 1) {
                    width = (width - 0.4) * ((currentArr_len - findIndex) / currentArr_len)
                    zIndex += findIndex
                    if(findIndex > 0) {
                        left = `calc(${99.6 - width}%)`
                    }
                }
            }
            return {
                top,
                left,
                height: height + 'px',
                display,
                width: width < 0 ? 0 : `calc(${width}% - 80px - 12px)`,
                zIndex,
                background: e.background,
                color: e.color,
                resize: e.isEdit ? 'vertical' : 'none'
            }
        }
        // 点击事件
        const getEvent = (e, index) => {
            if(!e.target.dataset.id) return
            selectedInfo.value = null
            // 监听点击的时间
            clickStart.value = new Date().getTime()
            dropIndex = index
            const data = {
                target: {
                    offsetTop: e.target.parentNode.offsetTop,
                    offsetLeft: e.target.parentNode.offsetLeft,
                    offsetWidth: e.target.parentNode.offsetWidth,
                    offsetHeight: e.target.parentNode.offsetHeight,
                    dataset: {
                        id: e.target.dataset.id
                    }
                },
                y: e.y,
                x: e.x
            }
            dropInfo = data
            canUp = true
            weekEvent.value[index]['active'] = true
            setTimeout(() => {
                if(canUp) {
                    dragStart(e, index)
                }else{
                    if(weekEvent.value[dropIndex]){
                        weekEvent.value[dropIndex]['active'] = false
                    }
                }
            }, 350)
        }
        // 拖拽开始
        const dragStart = (event, index) => {
            if(!weekEvent.value[index].isEdit){
                context.emit('getEvent', dropInfo)
                return false
            }
            selectedInfo.value = weekEvent.value[index]
            const windowWidth = document.querySelector('.scroll-container').clientWidth - 83
            const windowHeight = document.querySelector('.scroll-container').scrollHeight
            const cubeWidth = view.value == 'day' ? 0 : document.querySelectorAll('.week-data')[0].clientWidth
            const cubeHeight = view.value == 'day' ? document.querySelectorAll('.day-half')[0].clientHeight : document.querySelectorAll('.week-half')[0].clientHeight
            const startX = event.clientX - 5
            const startY = event.clientY - 5
            let disX = startX - event.target.parentNode.offsetLeft;
            let disY = startY - event.target.parentNode.offsetTop;
            const type = event.target.parentNode.dataset.type
            let move = false
            document.onmousemove = ev => {
                if(canUp && dropIndex > - 1 && type == 'event'){
                    let e = ev || window.event;
                    let l = e.clientX - disX;
                    let h = e.clientY - disY;
                    l = view.value == 'day' ? 0 : range(l, 0, windowWidth - event.target.parentNode.offsetWidth);
                    h = range(h, 0, windowHeight - event.target.parentNode.offsetHeight);
                    if(view.value != 'day') {
                        event.target.parentNode.style.left =`${l}px`;
                    }
                    event.target.parentNode.style.top = `${h}px`;
                    move = true
                }
            }
            document.onmouseup = (ev) => {
                document.onmousemove = null;
                if(canUp && dropIndex > - 1 && type == 'event' && move) {
                    if(!weekEvent.value[dropIndex].isEdit) return false
                    weekEvent.value[dropIndex]['active'] = false
                    let e = ev || window.event;
                    let d = Math.floor((e.clientX - disX) / cubeWidth) + 1 ;// 移动的距离
                    let h = Math.floor((e.clientY - disY) / cubeHeight) + 1; // 移动的高度
                    d = d <= 0 ? 1 : d
                    d = d >= 8 ? 7 : d
                    const item = weekEvent.value[dropIndex]
                    if(view.value == 'day') {
                        d = item.startDay
                    }
                    const index = events.value.findIndex(e => {
                        return e.id == item.id
                    })
                    const startHour = item.hours.split('-')[0].split(':')[0] * 60 * 60 * 1000
                    const startMin = item.hours.split('-')[0].split(':')[1] * 60 * 1000
                    const start = startHour + startMin
                    let newTime = item.start - (((item.startDay == 0 ? 7 : item.startDay) - d) * 24 * 60 * 60 * 1000) - (start - h * 30 * 60 * 1000)
                    const timeStart = new Date((view.value == 'day' ? date.value : week.value[0].fullDate) + ' 00:00:00').getTime()
                    const timeEnd =  new Date((view.value == 'day' ? date.value : week.value[len - 1].fullDate) + ' 23:59:59').getTime()
                    if(isNaN(newTime) || newTime < timeStart || newTime > timeEnd) {
                        return false
                    }
                    events.value[index].actionStartTime = format(new Date(newTime), 'yyyy-MM-dd HH:mm')
                    events.value[index].actionEndTime = format(new Date(new Date(events.value[index].actionStartTime).getTime() + item.release), 'yyyy-MM-dd HH:mm')
                    events.value[index].start = new Date(events.value[index].actionStartTime).getTime()
                    events.value[index].end = new Date(events.value[index].actionEndTime).getTime()
                    events.value[index] = formatTime(events.value[index])
                    getCurrentWeek()
                    context.emit('exchangeDate', events.value[index])
                    canUp = false
                }else{
                    context.emit('getEvent', dropInfo)
                }
            }
        }
        const range = (loc, min, max) => {
            if(loc > max) {
                return max;
            }else if(loc < min) {
                return min;
            }else {
                return loc;
            }
        }
        // 鼠标抬起
        const itemUp = () => {
            const end = new Date().getTime()
            if(end - clickStart.value < 350){
                canUp = false
                context.emit('getEvent', dropInfo)
                return false
            }
            if(weekEvent.value[dropIndex]){
                weekEvent.value[dropIndex]['active'] = false
            }
        }
        // 事件resize
        const eventResize = event => {
            let disY = event.clientY
            const height = event.target.parentNode.offsetHeight
            const cubeHeight = view.value == 'day' ? document.querySelectorAll('.day-half')[0].clientHeight : document.querySelectorAll('.week-half')[0].clientHeight
            // eslint-disable-next-line no-unused-vars
            const index = event.target.parentNode.dataset.index
            const type = event.target.parentNode.dataset.type
            let move = false
            document.onmousemove = ev => {
                let e = ev || window.event;
                let h = e.clientY - disY;
                h = height + h
                if(h > cubeHeight && type == 'event') {
                    event.target.parentNode.style.height = `${h}px`
                }
                move = true
            }
            document.onmouseup = () => {
                document.onmousemove = null
                if(index || index == 0 && type == 'event' && move){
                    let h = event.target.parentNode.offsetHeight
                    const item = weekEvent.value[index]
                    const TIME = item.hours.split('-')
                    const Time_Start = TIME[0].split(':')
                    const x = Time_Start[0] - 0 + Time_Start[1] / 60
                    const Time_End = (parseInt((h / 40 + x) * 100) / 100).toFixed(2) 
                    const endMin = Math.floor(Time_End.split('.')[1] * 0.01 * 60)
                    const newEnd = item.endDate + ' ' + (Time_End.split('.')[0] < 10 ? '0' + Time_End.split('.')[0] : Time_End.split('.')[0]) + ':' + (endMin < 10 ? ('0' + endMin) : endMin)
                    const _Index = events.value.findIndex(e => {
                        return e.id == item.id
                    })
                    if(!newEnd){
                        return false
                    }
                    events.value[_Index].actionEndTime = newEnd
                    events.value[_Index].end = new Date(events.value[_Index].actionEndTime).getTime()
                    events.value[_Index] = formatTime(events.value[_Index])
                    getCurrentWeek()
                    context.emit('exchangeDate', events.value[_Index])
                    canUp = false
                }
            }
        }
         // 模块跳转
        const jumpModel = (e, index) => {
            console.log(e, index)
        }
        // 切换事件状态
        const eventStatusChange = (e, index) => {
            weekEvent.value[index].complete = e
        }
        // 编辑信息
        const editInfo = (e) => {
            // let obj = {}
            // for(let key in e) {
            // obj[key] = e[key]
            // }
            context.emit('editInfo', e)
        }
         // 删除
        const delEvent = e => {
            context.emit('delEvent', e)
        }
        // 完成事件
        const completeEvent = (e, index) => {
            // weekEvent.value[index].complete = true
            context.emit('completeEvent', e)
        }
        // 鼠标滑动
        const itemOver = e => {
            const width = e.target.clientWidth
            const leftX = e.pageX - width
            if(leftX < 280) {
                placement.value = 'right-start'
            }else{
                placement.value = 'left-start'
            }
        }
         // 格式化时间
        const formatDurationTime = computed(() => {
            return item => {
                if(!item.actionStartTime) return ''
                return formatShortTime(item)
            }
        })
        // 审批通过
        const approverAccess = e => {
            context.emit('approverAccess', e)
        }
        // 审批拒绝
        const approverReject = e => {
            context.emit('approverReject', e)
        }
        // 查看
        const readInfo = (e) => {
            context.emit("readInfo", e);
        }
        watch(() => week.value, 
            () => {
                nextTick(() => {
                    getCurrentWeek()
                })
            }
        )
        watch(() => date.value, 
            () => {
                nextTick(() => {
                    getCurrentWeek()
                })
            }
        )
        watch(() => events.value,
            () => {
                nextTick(() => {
                    getCurrentWeek()
                })
            }
        )
        watch(() => dropData.value,
            (oldVal, newVal) => {
                dropMessage.value = oldVal || newVal
            },
            {
                deep: true
            }
        )
        onMounted(() => {
            nextTick(() => {
                getCurrentWeek()
            })
            document.addEventListener('mouseup',(e) =>{
                var _con = document.querySelector('event-model')
                if(_con){
                    if(!_con.contains(e.target)) {
                        if(dropIndex.value > -1) {
                            weekEvent.value[dropIndex.value]['drop'] = false
                            weekEvent.value[dropIndex.value]['active'] = false
                        }
                        selectedInfo.value = null
                    }
                }
            })
        })
        return {
            getStyle,
            weekEvent,
            getEvent,
            dragStart,
            selectedInfo,
            eventModel,
            // drag,
            dropIndex,
            itemUp,
            eventResize,
            jumpModel,
            eventStatusChange,
            editInfo,
            delEvent,
            completeEvent,
            placement,
            itemOver,
            formatDurationTime,
            userId,
            approverAccess,
            approverReject,
            View,
            readInfo
        }
    }
}
</script>

<style scoped lang="scss">
.event-wrapper{
  position: absolute;
  top: 0;
  left: 80px;
  width: 100%;
}
.event-wrapper .event-cell{
    position: absolute;
    z-index: 499;
    font-size: 12px;
    padding: 2px 5px;
    border-radius: 2px;
    background: #eaf4fc;
    color: var(--ss-color-primary);
    border: 1px solid #fff;
    box-sizing: border-box;
    cursor: pointer;
    display: block;
    &::after{
        content: "";
        position: absolute;
        right: 3px;
        bottom: 3px;
        width: 5px;
        height: 5px;
        border-right: 1px solid var(--ss-color-primary);
        border-bottom: 1px solid var(--ss-color-primary);
        opacity: .7;
    }
    .event-arrow{
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        cursor: s-resize;
        height: 5px;
    }
}
.event-wrapper .event-cell-disabled {
    &::after{
        display: none;
    }
}
.event-wrapper .event-cell .event-content{
    overflow: hidden;
    height: 100%;
    word-break: break-all;
}
.event-wrapper .event-drop{
    opacity: .5;
}
.event-wrapper .active{
    box-shadow: rgba(50, 50, 93, 0.25) 0px 2px 5px -1px, rgba(0, 0, 0, 0.3) 0px 1px 3px -1px;
}
.event-model{
    position: fixed;
    background: #eaf4fc;
    color: var(--ss-color-primary);
    z-index: 500;
    font-size: 12px;
    padding: 2px 5px;
    border-radius: 2px;
}
.event-data {
    display: inline;
}
.event-complete{
    text-decoration: line-through;
}
.event-detail-data{
    word-break: break-all;
    word-wrap: break-word;
}
:deep(.el-tag--small){
  .el-tag__content{
    max-width: 76px;
    overflow:hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
}
:deep(.showAllTag){
    .el-tag__content {
        max-width: unset;
    }
}
:deep(.el-button--small [class*=el-icon]+span){
  margin-left: 0;
}
</style>